// Foundation for Sites by ZURB
// foundation.zurb.com
// Licensed under MIT Open Source

////
/// @group functions
////

/// 用 CSS 术语确定值的真实性。假值包括 `null`，`none`, `0` 没有任何单位或者空列表
///
/// @param {Mixed} $val - 检查值
///
/// @returns {Boolean} 如果为真返回 true, 否则返回 false
@function has-value($val) {
  @if $val == null or $val == none {
    @return false;
  }
  @if type-of($val) == 'number' and strip-unit($val) == 0 {
    @return false;
  }
  @if type-of($val) == 'list' and length($val) == 0 {
    @return false;
  }
  @return true;
}

/// 指定内边距和外边距等属性中上、右、下、左方向上的值。无论传入了多少个值。如果您需要知道特定边的值，但不知道该值是否使用速记格式，请使用此函数
///
/// @param {List|Number} $val - 要分析的值。应该是一个速记的大小属性。例如："1em 2em 1em"
/// @param {Keyword} $side - 返回的边。应该是 `top`, `right`, `bottom` 或 `left`
///
/// @returns {Number} 基于 `$val` 和 `$side` 的单个值
@function get-side($val, $side) {
  $length: length($val);

  @if $length == 1 {
    @return $val;
  }
  @if $length == 2 {
    @return map-get((
      top: nth($val, 1),
      bottom: nth($val, 1),
      left: nth($val, 2),
      right: nth($val, 2),
    ), $side);
  }
  @if $length == 3 {
    @return map-get((
      top: nth($val, 1),
      left: nth($val, 2),
      right: nth($val, 2),
      bottom: nth($val, 3),
    ), $side);
  }
  @if $length == 4 {
    @return map-get((
      top: nth($val, 1),
      right: nth($val, 2),
      bottom: nth($val, 3),
      left: nth($val, 4),
    ), $side);
  }
}

/// 给一个简写的边框属性值，查找出某个边框属性的值
///
/// @param {List} $val - 简写的边框属性值
/// @param {Keyword} $elem - 边框属性。包含 `style`, `width` 或 `color`
///
/// @returns {Mixed} 如果值存在，返回这个值。如果值不再边框定义中，这个函数将返回 0px 宽，solid 样式, black 颜色
@function get-border-value($val, $elem) {
  // 查找宽度，样式和颜色，然后返回它
  @each $v in $val {
    $type: type-of($v);
    @if $elem == width and $type == 'number' {
      @return $v;
    }
    @if $elem == style and $type == 'string' {
      @return $v;
    }
    @if $elem == color and $type == 'color' {
      @return $v;
    }
  }

  // 默认
  $defaults: (
    width: 0,
    style: solid,
    color: #000,
  );

  @return map-get($defaults, $elem);
}

/// 在一个嵌套的 Map 中查找一个值
/// @link https://css-tricks.com/snippets/sass/deep-getset-maps/ Deep Get/Set in Maps
///
/// @param {Map} $map - 需要提取值的 Map
/// @param {String} $keys... - 获取值时使用的键
/// @returns {Mixed} 在 Map 找到的值
@function map-deep-get($map, $keys...) {
  @each $key in $keys {
    $map: map-get($map, $key);
  }
  @return $map;
}

/// 将 Map 转换为列表
/// @link http://hugogiraudel.com/2014/04/28/casting-map-into-list/
///
/// @param {Map} $map - 需要提取值得 Map
/// @param {String} $keep - 标识
///
/// @returns {List} 根据标识返回 `keys` 或 `values` 或全部
@function map-to-list($map, $keep: 'both') {
  $keep: if(index('keys' 'values', $keep), $keep, 'both');

  @if type-of($map) == 'map' {
    $keys: ();
    $values: ();

    @each $key, $val in $map {
      $keys: append($keys, $key);
      $values: append($values, $val);
    }

    @if $keep == 'keys' {
      @return $keys;
    } @else if $keep == 'values' {
      @return $values;
    } @else {
      @return zip($keys, $values);
    }
  }

  @return if(type-of($map) != 'list', ($value,), $map);

}

/// 安全的从 Map 中返回值
///
/// @param {Map} $map - 需要检索值的 Map
/// @param {String} $key - 键名
///
/// @returns {List} 查找到的值
@function map-safe-get($map, $key) {
  @if (type-of($map) == 'map' or (type-of($map) == 'list' and length($map) == 0)) {
    @if (map-has-key($map, $key)) {
      @return map-get($map, $key);
    } @else {
      @error 'Key: `#{$key}` is not available in `#{$map}`';
    }
  } @else {
    @error '`#{$map}` is not a valid map';
  }
}
